#include <arpa/inet.h>
#include <cstring>
#include <exception>
#include <iostream>
#include <openssl/ossl_typ.h>
#include <openssl/ssl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;

class sslctx {
public:
    bool Init(const string crt_file, const string key_file, const string ca);
    sslctx();
    virtual ~sslctx();

private:
    /* data */
};

bool sslctx::Init(const string crt_file, const string key_file, const string ca)
{
    // OPENSSL_init_ssl();被遗弃了
    SSL_CTX* pTempCtx = SSL_CTX_new(TLS_server_method());
    if (!pTempCtx) {
        cout << "CTX_NEW Failed" << endl;
        return false;
    }

    //加载CA证书
    int re = SSL_CTX_use_certificate_file(pTempCtx, crt_file.c_str(), SSL_FILETYPE_PEM);
    if (re <= 0) {
        cout << "CA ERROR" << endl;
        SSL_CTX_free(pTempCtx);
        return false;
    }

    //加载私钥
    int re2 = SSL_CTX_use_PrivateKey_file(pTempCtx, key_file.c_str(), SSL_FILETYPE_PEM);
    if (re2 <= 0) {
        cout << "Key Failed" << endl;
        SSL_CTX_free(pTempCtx);
        return false;
    }

    if (SSL_CTX_check_private_key(pTempCtx) <= 0) {
        cout << "Check Error" << endl;
        SSL_CTX_free(pTempCtx);
        return false;
    }
    return true;
}

int main(int argc, char* argv[])
{

    int serverfd = socket(AF_INET, SOCK_STREAM, 0);
    if (serverfd < 0) {
        cout << "Socket Error" << endl;
        return 1;
    }
    sockaddr_in ServerAddr;
    memset(&ServerAddr, 0, sizeof(ServerAddr));
    ServerAddr.sin_family = AF_INET;
    unsigned short serverport = 36666;
    ServerAddr.sin_port = htons(serverport);
    ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(serverfd, reinterpret_cast<sockaddr*>(&ServerAddr), sizeof(ServerAddr)) < 0) {
        cout << "Bind ERRROR" << endl;
        close(serverfd);
        return 1;
    }
    if (listen(serverfd, 1024) < 0) {
        cout << "Listen Error" << endl;
        close(serverfd);
        return 1;
    }
    while (1) {
        int tempfd = accept(serverfd, nullptr, 0);
    }
    return 0;
}
